<template>
  <div class="canvas-wrap" ref="canvasWrapRef">
    <canvas ref="canvas"></canvas>
  </div>
</template>

<script>
import { fabric } from 'fabric'
import {
  addCoordinate,
  initKeyBoardEvent,
  initMouseEvent,
  initImageSize,
} from './prevImg.js'

let fabCanvas = null
export default {
  name: 'prev-img',
  props: {
    draggable: {
      type: Boolean,
      default: true,
    },
    imageSrc: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      image: null,
      initImageScale: 1,
      isDrawing: false,
      startX: 0,
      startY: 0,
    }
  },
  watch: {
    draggable(val) {
      if (!val) {
        console.log('开始框选')
        // 移除所有选中
        fabCanvas.discardActiveObject()
      } else {
        console.log('开始移动')
      }
      fabCanvas.selection = !val
      // 修改所有图形可选中状态
      const rects = fabCanvas.getObjects()
      rects.forEach((item) => {
        item.set({
          selectable: val,
        })
      })
      fabCanvas.renderAll()
    },
  },
  mounted() {
    const { width, height } = this.$refs.canvasWrapRef.getBoundingClientRect()
    fabCanvas = new fabric.Canvas(this.$refs.canvas, {
      width,
      height,
    })
    fabCanvas.selection = !this.draggable
    addCoordinate(fabCanvas, fabric)
    this.bindDragEvent(fabCanvas)
    this.addImage(fabCanvas)
    initMouseEvent(fabCanvas, fabric)
    initKeyBoardEvent(fabCanvas, fabric)
  },
  methods: {
    // 旋转
    rotate(angle) {
      const currentAngle = this.image.get('angle')
      this.image.rotate(currentAngle + angle)
      fabCanvas.renderAll()
    },
    // 缩放
    zoom(scale) {
      console.log(scale, 'scale')
      let zoom = fabCanvas.getZoom() + parseFloat(scale)
      zoom = Math.max(0.2, zoom)
      zoom = Math.min(5, zoom)
      this.zoomTo(zoom)
    },
    zoomTo(num) {
      console.log(num, 'num')
      let backPoint = fabCanvas.getCenterPoint()
      fabCanvas.zoomToPoint(backPoint, num)
      fabCanvas.renderAll()
    },
    reset() {},
    addImage(canvas) {
      fabric.Image.fromURL(
        this.imageSrc,
        (img) => {
          this.image = img
          const { width, height } =
            this.$refs.canvasWrapRef.getBoundingClientRect()
          const {
            width: imageWidth,
            height: imageHeight,
            scale,
          } = initImageSize(this.image, { width, height })
          this.image.set({
            left: width / 2 - imageWidth / 2,
            top: height / 2 - imageHeight / 2,
            scaleX: scale,
            scaleY: scale,
            angle: 0,
            selectable: this.draggable,
            hasControls: true,
            hasBorders: false,
          })
          canvas.add(this.image)
          canvas.sendToBack(this.image)
        },
        null,
        { crossOrigin: 'Anonymous' },
      )
    },
    // 绑定拖拽事件
    bindDragEvent(canvas) {
      canvas.on('mouse:down', (e) => {
        if (this.draggable) return
        canvas.discardActiveObject()
        // 是否有选中对象
        // if (canvas.getActiveObject()) return
        this.isDrawing = true
        console.log('startDraw')
        const { x, y } = e.pointer
        this.startX = x
        this.startY = y
      })
      canvas.on('mouse:move', () => {
        if (this.draggable) return
        if (!this.isDrawing) return
        console.log('drawing')
      })
      canvas.on('mouse:up', (e) => {
        if (this.draggable) return
        // if (canvas.getActiveObject()) return
        this.isDrawing = false
        // this.$emit('update:draggable', true)
        console.log('endDraw')
        const { x, y } = e.pointer
        const left = Math.min(this.startX, x)
        const top = Math.min(this.startY, y)
        const width = Math.abs(this.startX - x)
        const height = Math.abs(this.startY - y)
        if (width < 10 || height < 10) {
          console.log('矩形框太小')
          return
        }
        // 获取缩放比例
        const scale = fabCanvas.getZoom()
        // 获取canvas的宽高
        const { width: canvasWidth, height: canvasHeight } = canvas
        // 缩放后的canvas宽高
        const scaleCanvasWidth = canvasWidth * scale
        const scaleCanvasHeight = canvasHeight * scale
        // 计算left和top
        const leftOffset = (scaleCanvasWidth - canvasWidth) / 2
        const topOffset = (scaleCanvasHeight - canvasHeight) / 2
        console.log(leftOffset, topOffset, 'leftOffset, topOffset')
        const rect = new fabric.Rect({
          left: (left + leftOffset) / scale,
          top: (top + topOffset) / scale,
          width: width / scale,
          height: height / scale,
          fill: 'rgba(255, 0, 0, 0)',
          stroke: 'red',
          strokeWidth: 1,
          lockMovementX: true, // 禁止移动
          lockMovementY: true, // 禁止移动
          selection: true,
        })
        canvas.add(rect)
        canvas.bringToFront(rect)
        canvas.setActiveObject(rect)
        canvas.requestRenderAll()
      })
      canvas.on('object:moving', (e) => {
        // if (this.draggable) return
        this.image.set({
          opacity: 0.5,
        })
        // 所有矩形跟着移动，未实现
      })
      // 移动结束
      canvas.on('object:moved', (e) => {
        // if (this.draggable) return
        this.image.set({
          opacity: 1,
        })
      })
    },
  },
}
</script>

<style scoped lang="scss">
.canvas-wrap {
  border: 1px solid#ccc;
}
</style>
